/*
 * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.io;

import java.lang.annotation.Native;

/**
 * 用于本地文件系统抽象的包私有抽象类。
 */

abstract class FileSystem {

    /* -- 规范化和构造 -- */

    /**
     * 返回本地文件系统的名称分隔符字符。
     */
    public abstract char getSeparator();

    /**
     * 返回本地文件系统的路径分隔符字符。
     */
    public abstract char getPathSeparator();

    /**
     * 将给定的路径名字符串转换为规范形式。如果字符串
     * 已经是规范形式，则直接返回。
     */
    public abstract String normalize(String path);

    /**
     * 计算此路径名字符串前缀的长度。路径名
     * 字符串必须是规范形式。
     */
    public abstract int prefixLength(String path);

    /**
     * 根据父路径解析子路径名字符串。
     * 两个字符串都必须是规范形式，结果
     * 也将是规范形式。
     */
    public abstract String resolve(String parent, String child);

    /**
     * 返回当两参数File构造函数中的父目录
     * 参数为空路径名时要使用的父路径名字符串。
     */
    public abstract String getDefaultParent();

    /**
     * 如有必要，对给定的URI路径字符串进行后处理。这在
     * win32上使用，例如，将"/c:/foo"转换为"c:/foo"。路径字符串
     * 仍然有斜杠分隔符；File类中的代码将在此方法返回后翻译它们。
     */
    public abstract String fromURIPath(String path);


    /* -- 路径操作 -- */

    /**
     * 判断给定的抽象路径名是否为绝对路径。
     */
    public abstract boolean isAbsolute(File f);

    /**
     * 判断给定的抽象路径名是否无效。
     */
    public abstract boolean isInvalid(File f);

    /**
     * 将给定的抽象路径名解析为绝对形式。由File类中的
     * getAbsolutePath和getCanonicalPath方法调用。
     */
    public abstract String resolve(File f);

    public abstract String canonicalize(String path) throws IOException;


    /* -- 属性访问器 -- */

    /* 简单布尔属性的常量 */
    @Native public static final int BA_EXISTS    = 0x01;
    @Native public static final int BA_REGULAR   = 0x02;
    @Native public static final int BA_DIRECTORY = 0x04;
    @Native public static final int BA_HIDDEN    = 0x08;

    /**
     * 返回由给定抽象路径名表示的文件或目录的简单布尔属性，
     * 如果不存在或发生其他I/O错误，则返回零。
     */
    public abstract int getBooleanAttributes(File f);

    @Native public static final int ACCESS_READ    = 0x04;
    @Native public static final int ACCESS_WRITE   = 0x02;
    @Native public static final int ACCESS_EXECUTE = 0x01;

    /**
     * 检查此进程是否可以访问由给定抽象路径名表示的文件或目录。
     * 第二个参数指定要检查的访问类型：ACCESS_READ、ACCESS_WRITE或ACCESS_EXECUTE。
     * 如果访问被拒绝或发生I/O错误，则返回false
     */
    public abstract boolean checkAccess(File f, int access);
    /**
     * 根据参数enable、access和owneronly，设置或取消对由给定抽象路径名
     * 表示的文件或目录的访问权限（仅对所有者或对所有人）。
     */
    public abstract boolean setPermission(File f, int access, boolean enable, boolean owneronly);

    /**
     * 返回由给定抽象路径名表示的文件或目录最后修改的时间，
     * 如果不存在或发生其他I/O错误，则返回零。
     */
    public abstract long getLastModifiedTime(File f);

    /**
     * 返回由给定抽象路径名表示的文件的字节长度，
     * 如果不存在、是目录或发生其他I/O错误，则返回零。
     */
    public abstract long getLength(File f);


    /* -- 文件操作 -- */

    /**
     * 使用给定路径名创建一个新的空文件。如果文件被创建则返回
     * <code>true</code>，如果具有给定路径名的文件或目录已存在则返回<code>false</code>。
     * 如果发生I/O错误则抛出IOException。
     */
    public abstract boolean createFileExclusively(String pathname)
        throws IOException;

    /**
     * 删除由给定抽象路径名表示的文件或目录，
     * 当且仅当操作成功时返回<code>true</code>。
     */
    public abstract boolean delete(File f);

    /**
     * 列出由给定抽象路径名表示的目录的元素。
     * 如果成功，返回命名目录元素的字符串数组；否则返回<code>null</code>。
     */
    public abstract String[] list(File f);

    /**
     * 创建由给定抽象路径名表示的新目录，
     * 当且仅当操作成功时返回<code>true</code>。
     */
    public abstract boolean createDirectory(File f);

    /**
     * 将由第一个抽象路径名表示的文件或目录重命名为
     * 第二个抽象路径名，当且仅当操作成功时返回<code>true</code>。
     */
    public abstract boolean rename(File f1, File f2);

    /**
     * 设置由给定抽象路径名表示的文件或目录的最后修改时间，
     * 当且仅当操作成功时返回<code>true</code>。
     */
    public abstract boolean setLastModifiedTime(File f, long time);

    /**
     * 将由给定抽象路径名表示的文件或目录标记为只读，
     * 当且仅当操作成功时返回<code>true</code>。
     */
    public abstract boolean setReadOnly(File f);


    /* -- 文件系统接口 -- */

    /**
     * 列出可用的文件系统根目录。
     */
    public abstract File[] listRoots();

    /* -- 磁盘使用情况 -- */
    @Native public static final int SPACE_TOTAL  = 0;
    @Native public static final int SPACE_FREE   = 1;
    @Native public static final int SPACE_USABLE = 2;

    public abstract long getSpace(File f, int t);

    /* -- 基础设施 -- */

    /**
     * 按字典顺序比较两个抽象路径名。
     */
    public abstract int compare(File f1, File f2);

    /**
     * 计算抽象路径名的哈希码。
     */
    public abstract int hashCode(File f);

    // 用于启用/禁用文件名规范化性能优化的标志
    static boolean useCanonCaches      = true;
    static boolean useCanonPrefixCache = true;

    private static boolean getBooleanProperty(String prop, boolean defaultVal) {
        String val = System.getProperty(prop);
        if (val == null) return defaultVal;
        if (val.equalsIgnoreCase("true")) {
            return true;
        } else {
            return false;
        }
    }

    static {
        useCanonCaches      = getBooleanProperty("sun.io.useCanonCaches",
                                                 useCanonCaches);
        useCanonPrefixCache = getBooleanProperty("sun.io.useCanonPrefixCache",
                                                 useCanonPrefixCache);
    }
}
